library {{pubName}}.api;

import 'package:http/http.dart' as http;
import 'package:jaguar_serializer/jaguar_serializer.dart';
{{#protoFormat}}
import 'package:jaguar_serializer_protobuf/proto_repo.dart';
{{/protoFormat}}
import 'package:jaguar_retrofit/jaguar_retrofit.dart';
import 'package:{{pubName}}/auth/api_key_auth.dart';
import 'package:{{pubName}}/auth/basic_auth.dart';
import 'package:{{pubName}}/auth/oauth.dart';
import 'package:jaguar_mimetype/jaguar_mimetype.dart';

{{#apiInfo}}{{#apis}}import 'package:{{pubName}}/api/{{classFilename}}.dart';
{{/apis}}{{/apiInfo}}
{{#models}}{{#model}}import 'package:{{pubName}}/model/{{classFilename}}{{#protoFormat}}.pb{{/protoFormat}}.dart';
{{/model}}{{/models}}


{{#jsonFormat}}
final _jsonJaguarRepo = JsonRepo()
{{#models}}{{#model}}{{^isEnum}}..add({{classname}}Serializer()){{/isEnum}}
{{/model}}{{/models}};
final Map<String, CodecRepo> defaultConverters = {
    MimeTypes.json: _jsonJaguarRepo,
};
{{/jsonFormat}}

{{#protoFormat}}
final _protoJaguarRepo = ProtoCodecRepo()
{{#models}}{{#model}}..add((data) => {{classname}}.fromBuffer(List<int>.from(data)))
{{/model}}{{/models}};
final _jsonJaguarRepo = ProtoCodecRepo(isJsonFormatEnabled: true)
{{#models}}{{#model}}..add((data) => {{classname}}.fromBuffer(List<int>.from(data)))
{{/model}}{{/models}};
final Map<String, CodecRepo> defaultConverters = {
    MimeTypes.json: _jsonJaguarRepo,
    MimeTypes.binary: _protoJaguarRepo,
};
{{/protoFormat}}


final _defaultInterceptors = [OAuthInterceptor(), BasicAuthInterceptor(), ApiKeyAuthInterceptor()];

class {{clientName}} {
    List<Interceptor> interceptors;
    String basePath = "{{basePath}}";
    Route _baseRoute;
    final Duration timeout;

    /**
    * Add custom global interceptors, put overrideInterceptors to true to set your interceptors only (auth interceptors will not be added)
    */
    {{clientName}}({List<Interceptor> interceptors, bool overrideInterceptors = false, String baseUrl, this.timeout = const Duration(minutes: 2)}) {
        _baseRoute = Route(baseUrl ?? basePath).withClient(globalClient ?? http.Client());
        if(interceptors == null) {
            this.interceptors = _defaultInterceptors;
        }
        else if(overrideInterceptors){
            this.interceptors = interceptors;
        }
        else {
            this.interceptors = List.from(_defaultInterceptors)..addAll(interceptors);
        }

        this.interceptors.forEach((interceptor) {
            _baseRoute.before(interceptor.before);
            _baseRoute.after(interceptor.after);
        });
    }

    void setOAuthToken(String name, String token) {
        (_defaultInterceptors[0] as OAuthInterceptor).tokens[name] = token;
    }

    void setBasicAuth(String name, String username, String password) {
        (_defaultInterceptors[1] as BasicAuthInterceptor).authInfo[name] = BasicAuthInfo(username, password);
    }

    void setApiKey(String name, String apiKey) {
        (_defaultInterceptors[2] as ApiKeyAuthInterceptor).apiKeys[name] = apiKey;
    }

    {{#apiInfo}}{{#apis}}
    /**
    * Get {{classname}} instance, base route and serializer can be overridden by a given but be careful,
    * by doing that all interceptors will not be executed
    */
    {{classname}} get{{classname}}({Route base, Map<String, CodecRepo> converters}) {
        if(base == null) {
            base = _baseRoute;
        }
        if(converters == null) {
            converters = defaultConverters;
        }
        return {{classname}}(base: base, converters: converters, timeout: timeout);
    }

    {{/apis}}{{/apiInfo}}
}
